(module mp2-soln
  (lib "eopl.ss" "eopl")
  
  (require "drscheme-init.scm")     
  (provide scan&parse value-of-aexp-string)
  
  (define the-lexer
    '((whitespace (whitespace)            skip)
      (number     (digit (arbno digit)) number)
      )
    )
  
  
  (define Arith-grammar
    '(
      (AExp (operator "(" AExp "," AExp ")") Composite-Exp)
      (AExp (number) const-AExp)
      (operator ("*") Times-oper)
      (operator ("+") Plus-oper)
      (operator ("-") Diff-oper)
      (operator ("/") Div-oper)
      )
    )
  
  ;; build a scanner with empty grammar 
  (define scan0 (sllgen:make-string-scanner the-lexer '()))
  
  ;; build data-types
  (sllgen:make-define-datatypes the-lexer Arith-grammar)
  
  ;; build scanner with grammar 
  (define just-scan
    (sllgen:make-string-scanner the-lexer Arith-grammar))
  
  ;; build parser 
  (define scan&parse 
    (sllgen:make-string-parser the-lexer Arith-grammar))
  
  ;; show the datatypes 
  (define show-the-datatypes 
    (lambda () (sllgen:show-define-datatypes the-lexer Arith-grammar)))
  
  (define exp1 "22")
  
  
  
  ;;value-of-aexp: AExp ==> number
  ;;usage: (value-of-aexp aexp)
  ;;purpose: Given a syntaxt tree produced by the above mentioned Grammar , 
  ;;this preocedure evaluates the arithmatic expression that is part of this Syntax Tree
  
  (define value-of-aexp
    (lambda(aexp)
      (cases AExp aexp
        (const-AExp(n) n)
        (Composite-Exp(op ex1 ex2)
                      (
                       (oper? op)
                       (value-of-aexp ex1) 
                       (value-of-aexp ex2))
                      ) 
        )
      )
    )
  
  
  ;;oper?: operator ==> operator-symbol
  ;;usage:(oper? op)
  ;;purpose: Given an instance of the  datatype operator ,  
  ;; this procedure returns the  actual operator for that data-structure.
  
  (define oper?
    (lambda (op)
      (cases operator op
        (Times-oper() *)
        (Plus-oper()  +)
        (Diff-oper() -)
        (Div-oper()  /)
        )
      )
    )
  (define to (Times-oper))                        
  (define po (Plus-oper))
  (define dfo (Diff-oper))
  (define dio (Div-oper)) 
  
  
  ;;;value-of-aexp-string: string ==> number
  ;;;usage:(value-of-aexp-string str)
  ;;;purpose:Gievn a sting which has a Arithmetic Expression , 
  ;;;  this  will convert that into an Arithmetic syntax tree and 
  ;;;  then Evaluate the generated tree using the value-of-aexp procedure.
  ;;;examples:  
  ;;;(value-of-aexp-string "*(/(+(2,4) , 2), /(10,2))") ==> 15  
  ;;;(value-of-aexp-string "*(2, /(10,2))") ==> 10
  ;;;(value-of-aexp-string "*(2, +(3,2))") ==> 10
  ;;; (value-of-aexp-string "22") ==> 22
  (define value-of-aexp-string 
    (lambda(str)
      (value-of-aexp (scan&parse str)
                     )
      )
    )
  )